# -*- coding: utf-8 -*-
"""
JIRA WEBSOC-7161
缺陷原因
1.由于鲁班后台创建套餐前端存在逻辑错误，导致周期性重置套餐的*ManualTask.limitType被错误的设置为limit
2.开通套餐时charges充值记录中的对应chargeType为plan，funcType为*ManualTask的limitType被设置为limit
3.周期性重置套餐脚本，每周期仅会重置limitType为period的*manualTask，被设为为limit的不会进行重置
4.已过期用户重新开通套餐，charges会将已有charges标记为delete，保证新开通的套餐limitType正确即可，当前脚本不需处理
处理流程
1.找出有问题的套餐
2.修改charges表的limitType，保障下次周期性重置正确
3.调整被影响客户的次数，重置当月balance套餐使用情况，受影响客户的使用次数将被重置
4.修改问题套餐的limitType为period
"""
import arrow
from mongoengine import Q
from flask import current_app as app
from app.db.models.balances import Balances
from app.db.models.charges import Charges
from app.db.models.packages import Packages

task_types = ["vul", "content", "securityEvent", "ssl", "asset"]


class UpdatePackages:

    def __init__(self):
        self.error_package_ids = []
        self.user_ids = []
        self.charge_ids = []
        self.datetime = arrow.utcnow().datetime
        self.init_error_package_ids()

    def init_error_package_ids(self):
        query = Q()
        for _ in task_types:
            query = query | Q(**{f"limit__{_}ManualTask__limitType": "limit", "chargeType": "plan"})
        only = ["limit", "name", "marks"]
        for package in Packages.objects.filter(query).only(*only):
            app.logger.info(f"{package.id} {package.name} {package.marks}")
            self.error_package_ids.append(package.id)
        app.logger.info(f"共{len(self.error_package_ids)}个套餐受影响:{self.error_package_ids}")

        self.user_ids = Balances.objects.filter(
            planId__in=self.error_package_ids,
            planExpireTime__gt=self.datetime
        ).distinct("uid")
        app.logger.info(f"共{len(self.user_ids)}个客户(未过期)受影响")

        self.charge_ids = Charges.objects.filter(
            uid__in=self.user_ids,
            chargeType="plan",
            limitType="limit",
            expireTime__gt=self.datetime,
            packId__in=self.error_package_ids,
            funcType__in=[f"{_}ManualTask" for _ in task_types],
            isDelete=False
        ).distinct("id")
        app.logger.info(f"共{len(self.charge_ids)}个充值记录需要处理")

    def run(self):
        for charge in Charges.objects.filter(pk__in=self.charge_ids):
            used = charge.used
            uid = charge.uid
            func_type = charge.funcType

            charge.limitType = "period"
            charge.used = 0
            balance = Balances.objects.filter(uid=uid).first()
            balance_data = getattr(balance.balance, func_type)
            balance_data.used -= used
            charge.save()
            balance.save()
            app.logger.info(f"用户: {charge.uid} {func_type} 处理完成")

        for package in Packages.objects.filter(pk__in=self.error_package_ids):
            limit = package.limit
            for _ in task_types:
                getattr(limit, f"{_}ManualTask").limitType = "period"
            package.save()
            app.logger.info(f"套餐: {package.marks} 处理完成")
